/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */
package com.googlecode.ivybeans.module.customizer;

import com.googlecode.ivybeans.module.IvyConfigurationHelper;
import com.googlecode.ivybeans.module.IvyLibraryController;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ResourceBundle;
import javax.swing.JComponent;
import javax.swing.JPanel;
import org.netbeans.api.project.Project;
import org.netbeans.api.project.ProjectManager;
import org.netbeans.api.project.ant.AntBuildExtender;
import org.netbeans.spi.project.ui.support.ProjectCustomizer;
import org.netbeans.spi.project.ui.support.ProjectCustomizer.Category;
import org.openide.ErrorManager;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileSystem;
import org.openide.filesystems.FileUtil;
import org.openide.filesystems.Repository;
import org.openide.util.Lookup;
import org.openide.util.NbBundle;

/**
 *
 * @author lforet
 */
public class CompositeCategoryProviderImpl implements ProjectCustomizer.CompositeCategoryProvider {

    private static final String IVY = "Ivy";
    private String name;

    public CompositeCategoryProviderImpl(String name) {
        this.name = name;
    }

    public Category createCategory(Lookup context) {
        Category toReturn = null;
        if (IVY.equals(name)) {
            ResourceBundle bundle = NbBundle.getBundle(CustomizerIvy.class);
            toReturn = ProjectCustomizer.Category.create(
                    IVY,
                    bundle.getString("CompositeCategoryProviderImpl.displayName"),
                    null,
                    null);
        }
        assert toReturn != null : "No category for name:" + name;
        return toReturn;
    }

    public JComponent createComponent(Category category, Lookup context) {
        String categoryName = category.getName();
        Project project = (Project) context.lookup(Project.class);
        if (IVY.equals(categoryName)) {
            CustomizerIvy customizer = new CustomizerIvy(project);
            category.setStoreListener(new StoreListener(customizer.getEditMediator()));
            return customizer;
        }
        return new JPanel();
    }

    public static CompositeCategoryProviderImpl createIvy() {
        return new CompositeCategoryProviderImpl(IVY);
    }

    private static class StoreListener implements ActionListener {

        private IvyLibraryUi.EditMediator em;
        private Project project;

        private StoreListener(IvyLibraryUi.EditMediator em) {
            this.em = em;
            project = em.getProject();
        }

        public void actionPerformed(ActionEvent e) {
//            try {
//                ProjectManager.mutex().writeAccess(new Mutex.ExceptionAction<Void>() {
//                    public Void run() throws IOException {
            try {
                IvyLibraryController ivyLibraryController = (IvyLibraryController) project.getLookup().lookup(IvyLibraryController.class);
                if (em.getIvyEnabledCheck().isSelected()) {
                    ivyLibraryController.setDescriptorFile(em.getSelectedDescriptorFile());
                    ivyLibraryController.setSettingsFile(em.getSelectedSettingsFile());
                    IvyConfigurationHelper.getInstance().store(project, em.getSelectedDescriptorFile(), em.getSelectedSettingsFile());
                    copyTemplate();
                    addBuildExtension();
                } else {
                    IvyConfigurationHelper.getInstance().clean(project);
                    ivyLibraryController.setDescriptorFile(null);
                    ivyLibraryController.setSettingsFile(null);
                    deleteTemplate();
                    removeBuildExtension();
                }
                ProjectManager.getDefault().saveProject(project);
            } catch (MalformedURLException ex) {
                ErrorManager.getDefault().notify(ex);
            } catch (IOException ex) {
                ErrorManager.getDefault().notify(ex);
            }
//                        return null;
//                    }
//                });
//            } catch (MutexException ex) {
//                ErrorManager.getDefault().notify(ex.getException());
//            }
        }

        private void copyTemplate() throws IOException {
            FileObject projDir = project.getProjectDirectory();
            FileObject ivyBuildFile = projDir.getFileObject("nbproject/ivy-impl.xml"); // NOI18N
            if (ivyBuildFile == null) {
                FileSystem sfs = Repository.getDefault().getDefaultFileSystem();
                FileObject templateFO = sfs.findResource("Templates/ivybeans/ivy-impl.xml"); // NOI18N
                if (templateFO != null) {
                    FileUtil.copyFile(templateFO, projDir.getFileObject("nbproject"), "ivy-impl"); // NOI18N
                }
            }
        }

        private void deleteTemplate() throws IOException {
            FileObject projDir = project.getProjectDirectory();
            FileObject ivyBuildFile = projDir.getFileObject("nbproject/ivy-impl.xml"); // NOI18N
            if (ivyBuildFile != null) {
                boolean isDeleted = FileUtil.toFile(ivyBuildFile).delete();
                assert isDeleted;
            }
        }

        private void addBuildExtension() throws IOException {
            FileObject projDir = project.getProjectDirectory();
            FileObject ivyBuildFile = projDir.getFileObject("nbproject/ivy-impl.xml"); // NOI18N
            AntBuildExtender extender = project.getLookup().lookup(AntBuildExtender.class);
            assert extender != null;
            assert ivyBuildFile != null;
            if (extender.getExtension("ivy") == null) { // NOI18N
                AntBuildExtender.Extension ext = extender.addExtension("ivy", ivyBuildFile); // NOI18N
                ext.addDependency("-pre-pre-compile", "-ivy-retrieve"); // NOI18N
                ext.addDependency("-post-clean", "-ivy-clean"); // NOI18N
            }
//            ProjectManager.getDefault().saveProject(project);
        }

        private void removeBuildExtension() throws IOException {
            AntBuildExtender extender = project.getLookup().lookup(AntBuildExtender.class);
            assert extender != null;
            if (extender.getExtension("ivy") != null) { // NOI18N
                extender.removeExtension("ivy"); // NOI18N
            }
//            ProjectManager.getDefault().saveProject(project);
        }
    }
}
